<template>
  <view class="_wrapper">
    <view class="_content">
      <!-- 标题， 如果是地址，并且有值的情况下，不展示标题 -->
      <view :class="'label ' + (labelMinWidth ? 'labelMinWidth' : '')" v-if="!(!isEmptyObj(value) && comType === 'address')">
        <view class="required-flag">{{ !!required ? '*':'' }}</view>
        <text class="txt">{{ title }}</text>
      </view>
      <view class="_right">
        <!-- 输入框 -->
        <view class="_com-box _input-box" v-if="comType === 'input'">
          <input class="_input" :maxlength="maxLength" :disabled="disabled" :value="value" :type="inputType" @input="inputValueChange"
            :placeholder="placeholder" placeholder-class="_input-placeholder" />
          <view v-if="unit" class="_unit">{{ unit }}</view>
          <view v-if="desc" class="_desc">{{ desc }}</view>
        </view>
        <!-- radio group -->
        <view class="_com-box _radio-group" v-if="comType === 'radio-group'">
          <view :class="'radio-item ' + (item.value === value ? 'checked' : '')" v-for="item in options" :key="item.value" @tap="radioChange(item)">
            <text class="txt">{{ item.label }}</text>
          </view>
        </view>
        <!-- 普通下拉选择 -->
        <view class="_com-box _select-box" v-if="comType === 'select'" @tap="toggle">
          <view v-if="value" class="_input">{{ getValue(value) }}</view>
          <view v-else class="_input-placeholder">{{ placeholder }}</view>
          <image :class="down ? '_arrow-icon _down' : '_arrow-icon'" :src="stitchingURL('icons/arrow-gray')"></image>
        </view>
        <!-- 页面跳转 -->
        <view class="_com-box _select-box" v-if="comType === 'jumpPage'">
          <view v-if="value" class="_input">{{ value }}</view>
          <view v-else class="_input-placeholder">{{ placeholder }}</view>
          <image :class="down ? '_arrow-icon _down' : '_arrow-icon'" :src="stitchingURL('icons/arrow-gray')"></image>
        </view>
        <!-- 图片上传 -->
        <view class="_com-box _upload-img-comp" v-if="comType === 'uploadImg'">
          <view class="_upload-img-box">
            <view v-if="!value && !disabled" class="no-img-box _upload-img-box-c" @tap="uploadImage">
              <uni-icons type="plusempty" size="30" color="#461E50"></uni-icons>
            </view>
            <view v-else class="has-img-box _upload-img-box-c">
              <view v-if="(tempFilePath || value) && !disabled" @tap.stop="delImage" class="del-btn">
                <uni-icons type="closeempty" size="16" color="#fff"></uni-icons>
              </view>
              <image class="upload-img" @tap='previewImage' :src="tempFilePath"></image>
            </view>
          </view>
        </view>
        <!-- 时间选择 -->
        <view class="_com-box _date-picker-box" v-if="comType === 'datetimerange'" @tap="visible = true">
          <view v-if="value" class="_input">{{ value }}</view>
          <view v-else class="_input-placeholder">{{ placeholder }}</view>
          <image :class="down ? '_arrow-icon _down' : '_arrow-icon'" :src="stitchingURL('icons/arrow-gray')"></image>
        </view>
        <!-- 时间选择 -->
        <uni-datetime-picker type="date" v-if="comType === 'date'" @change="changeValue" :value="value">
          <view class="_com-box _date-picker-box">
            <view v-if="value" class="_input">{{ value }}</view>
            <view v-else class="_input-placeholder">{{ placeholder }}</view>
            <image :class="down ? '_arrow-icon _down' : '_arrow-icon'" :src="stitchingURL('icons/arrow-gray')"></image>
          </view>
        </uni-datetime-picker>
        <!-- 弹窗下拉框 -->
        <!-- <picker v-if="comType === 'picker-select'" @change="changeValue" :value="value" :range="options.map(v => v.label)">
        </picker> -->
        <view v-if="comType === 'picker-select'" class="_com-box" @tap="pickerVisible = true">
          <view v-if="value" class="_input tar">{{ getOptionsLabel(value) }}</view>
          <view v-else class="_input-placeholder">{{ placeholder }}</view>
          <image :class="down ? '_arrow-icon _down' : '_arrow-icon'" :src="stitchingURL('icons/arrow-gray')"></image>
        </view>
        <view v-if="comType === 'click-select'" class="_com-box" @tap="$emit('onClick')">
          <view v-if="value" class="_input tar">{{ valueTitle }}</view>
          <view v-else class="_input-placeholder">{{ placeholder }}</view>
          <image :class="down ? '_arrow-icon _down' : '_arrow-icon'" :src="stitchingURL('icons/arrow-gray')"></image>
        </view>
        <!-- Switch -->
        <view v-if="comType === 'switch'" class="_com-box switch">
          <switch 
            @change="inputValueChange" 
            :checked="value === checked" 
            :value="value"
						color="#30302F"
          />
        </view>
        <!-- address -->
        <view v-if="comType === 'address'" class="_com-box"  @click.stop="$emit('onClick')">
          <view v-if="isEmptyObj(value)" class="_input-placeholder">{{ placeholder }}</view>
          <image v-if="isEmptyObj(value)" :class="down ? '_arrow-icon _down' : '_arrow-icon'" :src="stitchingURL('icons/arrow-gray')"></image>
          <template v-if="!isEmptyObj(value)">
            <slot></slot>
          </template>
        </view>
      </view>
    </view>
    <!-- 普通下拉框的下拉选项 -->
    <view class="_select-wrapper" v-if="selectedList.length > 0 && (down || step > 0)">
      <view class="_select-list">
        <view :class="currentValue === item[dataValue] ? '_select-item checked' : '_select-item'" @click="onChange(item)"
          v-for="(item, index) in selectedList" :key="item[dataValue]">{{ item[dataLabel] }}</view>
      </view>
    </view>

    <xl-date-time-picker @onClose="visible=false" @onChange="dateTimeChange" :visible="visible" />
    <xl-select-picker @onClose="pickerVisible=false" @onChange="pickerChange" :visible="pickerVisible" :options="options" />
  </view>
</template>

<script>
import xlDateTimePicker from './xl-date-time-picker.vue';
import xlSelectPicker from './xl-select-picker.vue';
import {
  stitchingURL,
  isEmptyObj,
  showToast,
} from "@/common/util.js";
import { getStorage } from '@/common/storage';
import config from '@/common/config.js';

let self = this;

export default {
  name: "uni-form-field",
  components: {
    xlDateTimePicker,
    xlSelectPicker
  },
  computed: {
    selectedList() {
      if (!this.hasChildren) {
        return this.options;
      }
      if (this.step > 0 && this.value) {
        const arr = this.options.find(v => v[this.dataValue] === this.value) || {};
        return arr[this.childrenName] || [];
      }
      return this.options;
    },
    currentValue() {
      if (!this.hasChildren) {
        return this.value;
      }
      return this.step > 0 && this.value ? this.childrenValue : this.value;
    }
  },
  props: {
    disabled: {
      type: Boolean,
      default: false
    },
    checked: {
      type: [String, Number, Boolean],
      default: false
    },
    value: {
      default: undefined
    },
    valueTitle: {
      type: String,
      default: ""
    },
    childrenValue: {
      type: [String, Number],
      default: ''
    },
    placeholder: {
      type: String,
      default: ''
    },
    hasChildren: {
      type: Boolean,
      default: false
    },
    comType: {
      type: String,
      default: 'input'
    },
    title: {
      type: String,
      default: '商品名称'
    },
    required: {
      type: Boolean,
      default: false
    },
    unit: {
      type: String,
      default: ''
    },
    desc: {
      type: String,
      default: ''
    },
    options: {
      type: Array,
      default: () => []
    },
    parser: {
      type: Function,
      default: null
    },
    formatter: {
      type: Function,
      default: null
    },
    dataLabel: {
      type: String,
      default: 'label'
    },
    dataValue: {
      type: String,
      default: 'value'
    },
    childrenName: {
      type: String,
      default: 'children'
    },
    tempFilePath: {
      type: String,
      default: undefined
    },
    maxLength: {
      type: [Number, String],
      default: -1
    },
    inputType: {
      type: String,
      default: 'text'
    },
    labelMinWidth: {
      type: Boolean,
      default: false
    }
  },
  data() {
    return {
      down: false,
      step: 0,
      visible: false,
      pickerVisible: false
    }
  },
  methods: {
    stitchingURL,
    isEmptyObj,
    setStep(val) {
      this.step = val;
    },
    getOptionsLabel(value) {
      if (!value && value !== 0) {
        return '';
      }
      const curr = this.options.find(v => v.value === value);
      return curr ? curr.label : '';
    },
    changeValue(value) {
      this.$emit('change', value);
    },
    radioChange(item) {
      if (this.disabled) {
        return ;
      }
      this.changeValue(item.value);
    },
    dateTimeChange(val) {
      this.changeValue(val);
      this.visible = false;
    },
    pickerChange(val) {
      this.changeValue(val);
      this.pickerVisible = false;
    },
    inputValueChange(e) {
      this.changeValue(e.detail.value);
    },
    getClassName() {
      return '_select-item'
    },
    getValue(val) {
      const item = this.options.find(v => v[this.dataValue] === val) || {};
      return item[this.dataLabel] || '';
    },
    onChange(value) {
      if (!this.hasChildren) {
        this.down = false;
        this.changeValue(value);
        return;
      }
      if (this.step === 0) {
        if (value || value[this.childrenName] || value[this.childrenName].length) {
          this.step += 1;
        }
        this.down = false;
        this.changeValue({
          value,
          childrenValue: undefined
        });
        return;
      }
      this.changeValue({
        value: this.options.find(v => v[this.dataValue] === this.value),
        childrenValue: value
      });
    },
    toggle() {
      if (!this.down && this.hasChildren && this.step > 0) {
        this.step = 0;
        this.changeValue({
          value: this.value,
          childrenValue: undefined
        });
      }
      this.down = !this.down;
    },
    uploadCallBack(filePath) {
      uni.showLoading({
        title: "上传中",
        mask: true,
      });
      uni.uploadFile({
        url: config.BASEURL + uni.$api.commonUpload,
        filePath,
        name: "file",
        header: {
          Authorization: "Bearer " + getStorage('token'),
          'x-token': getStorage('token'),
        },
        formData: {
          businessCode: 'identification_code'
        },
        success: (uploadFileRes) => {
          uni.hideLoading();
          try {
            let fileRes = JSON.parse(uploadFileRes.data);
            if (fileRes.code === '0') {
              // 展示图片
              self.$emit('change', {
                value: fileRes.data,
                tempFilePath: filePath
              });
              showToast("上传成功", 2000, "success");
            } else {
              showToast(fileRes.msg, 3000);
            }
          } catch (error) {
            showToast("上传失败", 2000);
          }
        },
        fail: () => {
          uni.hideLoading();
        }
      });
    },
    uploadImage() {
      self = this;
      if (uni.chooseMedia) {
        uni.chooseMedia({
          count: 1, //默认9
          resp_type: 1,
          mediaType: ['image', 'video'],
          sizeType: ["original", "compressed"], //可以指定是原图还是压缩图，默认二者都有
          sourceType: ["album", "camera"], //从相册选择
          success: function (chooseImageRes) {
            const path = chooseImageRes.tempFiles[0];
            if (path.size > 10 * 1000 * 1000) {
              showToast('仅支持上传10M以内的图片');
              return;
            }
            self.uploadCallBack(path.tempFilePath);
          },
        });
      } else {
        uni.chooseImage({
          count: 1, //默认9
          resp_type: 1,
          sizeType: ["original", "compressed"], //可以指定是原图还是压缩图，默认二者都有
          sourceType: ["album", "camera"], //从相册选择
          success: function (chooseImageRes) {
            const path = chooseImageRes.tempFilePaths[0];
            if (path.size > 10 * 1000 * 1000) {
              showToast('仅支持上传10M以内的图片');
              return;
            }
            self.uploadCallBack(path);
          },
        });
        }
    },
    previewImage() {
      if (this.tempFilePath) {
        const goodsPic = this.tempFilePath;
        // 预览图片
        uni.previewImage({
          current: goodsPic,
          urls: [goodsPic]
        })
      }
    },
    delImage() {
      uni.showModal({
        content: "确定删除该照片吗？",
        confirmText: "确认",
        confirmColor: "#FF4953",
        success: res => {
          if (res.confirm) {
            this.$emit('change', {
              value: undefined,
              tempFilePath: undefined
            });
          }
        },
      });
    },
  },
  onLoad() {
    self = this;
  },
  watch: {
    value(val) {
      if (!val || !this.parser || !this.formatter) {
        return;
      }
      if (this.parser(val)) {
        this.$emit('change', this.formatter(val));
      }
    }
  }
}
</script>
<style lang="scss">
._time-wrapper {
  width: 100%;
  height: 600upx;
}
._input-placeholder {
  font-weight: 400;
  font-size: 28upx;
  line-height: 48upx;
  color: #A9A9A9;
}
._date-picker-box ._input, ._picker-select-box ._input{
  text-align: right;
  font-weight: 700;
  line-height: 39upx;
}
</style>
<style lang="scss" scoped>
.picker-view {
		width: 100%;
		height: 600upx;
		margin-top: 20upx;
	}
	.item {
		line-height: 100upx;
		text-align: center;
	}
._wrapper {
  width: 100%;
  ._content {
    padding: 16upx 0;
    display: flex;
    justify-content: space-between;
    .label {
      display: flex;
      justify-content: flex-end;
      align-items: flex-start;
      height: 80upx;
      align-items: center;
      margin-right: 30upx;
      &.labelMinWidth {
        min-width: 130upx;
      }

      .required-flag {
        width: 15upx;
        font-weight: 600;
        font-size: 28upx;
        color: #FF4D56;
        line-height: 39rpx;
        margin-right: 6upx;
      }
      .txt {
        font-weight: 400;
        font-size: 28upx;
        line-height: 48upx;
        text-align: left;
        color: #30302F;
      }
    }

    ._right {
      flex: 1;
      display: flex;
      justify-content: flex-end;
      align-items: center;

      ._com-box {
        flex: 1;
        display: flex;
        justify-content: flex-end;
        align-items: center;
        padding: 16upx 0;
        border-radius: 23upx;

        &._upload-img-comp {
          padding-right: 48upx;
        }

        &._input-box {
          padding-right: 40upx;
          background-color: #f5f5f5;
        }
        &._radio-group {
          display: flex;
          justify-content: flex-end;
          flex-wrap: wrap;
          .radio-item {
            margin-right: 30upx;
            padding: 10upx 20upx;
            border-radius: 23upx;
            background: #F5F5F5;
            min-width: 100upx;
            display: flex;
            justify-content: center;
            align-items: center;
            &:last-child {
              margin-right: 0;
            }
            .txt {
              color: #30302F;
              font-family: PingFang SC;
              font-size: 28upx;
              font-style: normal;
              font-weight: 400;
              line-height: normal;
            }
            &.checked {
              background-color: #461E50;
              .txt {
                color: #FFFFFF;
              }
            }
          }
        }
       

        ._input {
          flex: 1;
          height: 48upx;
          font-weight: 700;
          font-size: 28upx;
          line-height: 48upx;
          text-align: left;
          color: #30302F;
          outline: none;
          padding-left: 40upx;
          &.tar {
            text-align: right;
          }
        }

        ._input-placeholder {
          font-weight: 400;
          font-size: 28upx;
          line-height: 39upx;
          text-align: right;
          color: #A9A9A9;
        }

        ._unit {
          font-weight: 600;
          font-size: 28upx;
          line-height: 48upx;
          text-align: right;
          color: #30302F;
          margin-left: 16upx;
        }
        ._desc {
          font-size: 24upx;
          line-height: 39upx;
          text-align: right;
          color: #A9A9A9;
          margin-left: 16upx;
        }

        ._fix-box {
          width: 48upx;
          height: 48upx;
        }

        ._arrow-icon {
          width: 48upx;
          height: 48upx;

          &._down {
            transform: rotate(90deg);
            -ms-transform: rotate(90deg);
            /* IE 9 */
            -webkit-transform: rotate(90deg);
            /* Safari and Chrome */
          }
        }

        ._upload-img-box {
          width: 160upx;
          height: 160upx;
          background: #f5f5f5;
          border-radius: 23upx;
          overflow: hidden;

          ._upload-img-box-c {
            width: 100%;
            height: 100%;
            display: flex;
            align-items: center;
            justify-content: center;

            &.has-img-box {
              position: relative;

              .upload-img {
                width: 100%;
                height: 100%;
              }

              .del-btn {
                position: absolute;
                right: 0;
                top: 0;
                width: 50upx;
                height: 48upx;
                z-index: 1;
                background: #30302F;
                border-radius: 0upx 23upx 0upx 38upx;
                display: flex;
                justify-content: flex-end;
                align-items: flex-start;

                ._icon {
                  width: 20upx;
                  height: 20upx;
                  margin-right: 12upx;
                  margin-top: 14upx;
                }
              }
            }

            &.no-img-box {
              .upload_icon {
                width: 66upx;
                height: 66upx;
              }
            }
          }
        }
      }
    }
  }

  ._select-wrapper {
    padding-left: 56upx;
    padding-right: 56upx;

    ._select-list {
      display: flex;
      flex-direction: row;
      flex-wrap: wrap;
      justify-content: flex-start;
      margin-left: -16upx;
      margin-top: -32upx;

      ._select-item {
        padding: 16upx 24upx;
        background: #F5F5F5;
        border-radius: 23upx;
        font-weight: 400;
        font-size: 28upx;
        line-height: 39upx;
        color: #30302F;
        margin-top: 32upx;
        margin-left: 16upx;

        &.checked {
          background: #1F1F1F;
          color: #FFFFFF;
        }
      }
    }
  }
}
</style>